home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Very Best of Atari Inside
/
The Very Best of Atari Inside 1.iso
/
mint
/
mntlb20
/
lib
/
sozobon
/
bcopy.s
< prev
next >
Wrap
Text File
|
1992-01-11
|
2KB
|
83 lines
; void bcopy(void *src, void *dst, long cnt)
; handle overlap (both ways), odd/even alignment etc
; ++jrb bammi@dsrgsun.ces.cwru.edu
;
.text
.even
.globl _bcopy
_bcopy:
move.l 4(sp),a0 ; src -> a0
move.l 8(sp),a1 ; dst -> a1
move.l 12(sp),d0 ; cnt -> d0
ble return ; cnt <= 0
move.l d2,-(sp) ; save d2
; check overlap
move.l a0,d1 ; (abs(src - dst)) < cnt => overlap
sub.l a1,d1
bge L1
neg.l d1
L1: cmp.l d1,d0
bgt overlap
; check for odd src or dst
move.w a0,d1
move.w a1,d2
eor.b d1,d2
btst #0,d2
bne oddeven
btst #0,d1
beq eveneven
move.b (a0)+,(a1)+ ; odd odd
subq.l #1,d0 ; now even even
eveneven: ; may want long alignment for 020/030 etc
move.l d0,d1
and.b #$1c,d1 ; 4 bytes/copy 32 bytes max/iter
lsr.l #1,d1 ; calc index into loop (each move.l == 2bytes)
neg.l d1 ;
add.l #18,d1 ; 16 + 2 bytes for jmp ext word - d1 == index
jmp 0(pc,d1) ; dive into loop at appro spot
loop1:
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
sub.l #32,d0
bge loop1
btst #1,d0
beq L4
move.w (a0)+,(a1)+ ; residual word
L4: btst #0,d0
beq ret
move.b (a0),(a1) ; residual byte
ret: move.l (sp)+,d2
return: rts
oddeven:
upcopy: ; byte-by-byte forward
subq.l #1,d0
blt ret
move.b (a0)+,(a1)+
bra upcopy
overlap:
cmp.l a0,a1
bmi upcopy ; (src > dst) go do byte/byte forward copy
add.l d0,a0 ; otherwise backwards copy
add.l d0,a1 ; note we use predec so 1 is not sub from addr
downcopy: ; byte-by-byte backward
subq.l #1,d0
blt ret
move.b -(a0),-(a1)
bra downcopy